﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Navigation;
using System.Xml.Linq;

using System.Windows.Data;
using System.Windows.Threading;
using System.ComponentModel;
using System.Windows.Media.Imaging;

using PermDoc.GDI;
using PermDoc.Ctrl.Docs;

namespace PermDoc
{

    public partial class PageDoc : Page, INotifyPropertyChanged
    {

        #region Members
        long FirstClickTime;
        public event PropertyChangedEventHandler PropertyChanged;
        #endregion

        #region Constructors
        public PageDoc()
        {
            InitializeComponent();
        }
        #endregion

        #region Page Events
        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
        }
        private void Page_Loaded(object sender, RoutedEventArgs e)
        {

            Exception ret = null;

            #region GDI

            FirstClickTime = DateTime.Now.Ticks;
            Storyboard sb = new Storyboard();
            DoubleAnimation da = new DoubleAnimation();
            da.From = -3.0;
            da.To = 3.0;
            da.Duration = new Duration(TimeSpan.FromMilliseconds(1000));
            da.AutoReverse = true;
            da.RepeatBehavior = RepeatBehavior.Forever;

            button1.RenderTransform = new TranslateTransform();
            Storyboard.SetTarget(da, button1.RenderTransform);
            Storyboard.SetTargetProperty(da, new PropertyPath("Y"));
            sb.Children.Add(da);
            sb.Begin();

            #endregion

            #region Bind

            App._SelDoc_data.Clear();
            PagedCollectionView view = new PagedCollectionView(App._SelDoc_data);
            gv.ItemsSource = view;

            oBtnOpenDocInDeepZoom.NavigateUri =
                new Uri(@"/PageDeepZoom.xaml", UriKind.Relative);

            if (App.SelectedDocumentTopic != null)
            {
                oBtnOpenDocInDeepZoom.IsEnabled = false;
                oBtnOpenDocInBrowser.IsEnabled = true;
                oBtnOpenDocInBrowser.NavigateUri =
                    new Uri(@"http://sp.korablik.local/shops/DocLib/"
                        + App.SelectedDocumentTopic.No, UriKind.Absolute);

                oTxtNo.DataContext = App.SelectedDocumentTopic;
                oTxtDocDate.DataContext = App.SelectedDocumentTopic;
                oTxtDocCreated.DataContext = App.SelectedDocumentTopic;
                oTxtDocAuthor.DataContext = App.SelectedDocumentTopic;
                oTxtDocModify.DataContext = App.SelectedDocumentTopic;
                oTxtDocEditor.DataContext = App.SelectedDocumentTopic;
                oTxtDocState.DataContext = App.SelectedDocumentTopic;
                oTxtDocShop.DataContext = App.SelectedDocumentTopic;
                oTxtDocKontr.DataContext = App.SelectedDocumentTopic;
                oTxtDocNo_Doc.DataContext = App.SelectedDocumentTopic;
            }
            else
            {
                oBtnOpenDocInDeepZoom.IsEnabled = false;
                oBtnOpenDocInBrowser.IsEnabled = false;
            }

            #endregion

            #region WebClient - Load detals Data

            if (App.SelectedDocumentTopic != null)
            {

                string UrlStr =
@"http://sp.korablik.local:98/ws/SP/PermDocs_FilesInfo_ByDocSetID.aspx?intID=" 
+ App.SelectedDocumentTopic.ИД
+ @"&guid=" + Guid.NewGuid().ToString();

                try
                {
                    WebClient wc = new WebClient();
                    wc.DownloadStringCompleted +=
                        new DownloadStringCompletedEventHandler(Invalidate);
                    Uri myUri = new Uri(UrlStr, UriKind.Absolute);
                    wc.DownloadStringAsync(myUri);
                }
                catch (Exception err)
                {
                    ret = new Exception(err.Message, err);
                }

            }

            #endregion

        }
        private void Page_Unloaded(object sender, RoutedEventArgs e)
        {
        }
        #endregion

        #region Controls Events
        protected void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
        private void Button_MouseLeftButtonDown(object sender, MouseButtonEventArgs args)
        {
            if (((UIElement)args.OriginalSource) == null)
                return;

            //Get click position relative to the clicked object
            Point p = args.GetPosition((UIElement)args.OriginalSource);

            //Determine simple moment arm and direction against clicked object on both x & y axes.
            double DirectionalScalarY = (p.Y - (button1.RenderSize.Height / 2)) / (button1.RenderSize.Height / 2);
            double DirectionalScalarX = ((button1.RenderSize.Width / 2) - p.X) / (button1.RenderSize.Width / 2);


            //Apply only if on the top 10% of the clickable frame.
            if (DirectionalScalarY < -.90)
            {
                //Simulated double-click.  Each tick is .1 ms.
                //Setting double-click definition as two clicks
                //within 250 ms.
                if (DateTime.Now.Ticks - FirstClickTime < 10000 * 250)
                    FlipFrame(DirectionalScalarX);

                FirstClickTime = DateTime.Now.Ticks;
                return;
            }


            Storyboard sb = new Storyboard();
            //            button1.Projection = new PlaneProjection();

            DoubleAnimationUsingKeyFrames da = BuildKeyFrames(1.0, 80.0, 1.0, 35.0, DirectionalScalarX, 5.0);
            Storyboard.SetTarget(da, button1.Projection);
            Storyboard.SetTargetProperty(da, new PropertyPath("RotationY"));
            sb.Children.Add(da);

            da = BuildKeyFrames(1.0, 80.0, 1.0, 35.0, DirectionalScalarY, 5.0);
            Storyboard.SetTarget(da, button1.Projection);
            Storyboard.SetTargetProperty(da, new PropertyPath("RotationX"));
            sb.Children.Add(da);

            sb.Begin();
        }
        private void Border_MouseMove(object sender, MouseEventArgs args)
        {
            if (PlaceHolder == null)
                return;

            if (PlaceHolder.Effect == null)
                return;

            Point p = new Point();
            p.X = args.GetPosition(button1).X / (button1.RenderSize.Width);
            p.Y = args.GetPosition(button1).Y / (button1.RenderSize.Height);

            if (PlaceHolder.Effect.GetType().Equals(typeof(RippleEffect)))
                ((RippleEffect)PlaceHolder.Effect).Center = p;

            if (PlaceHolder.Effect.GetType().Equals(typeof(SmoothMagnifyEffect)))
                ((SmoothMagnifyEffect)PlaceHolder.Effect).Center = p;
        }
        private void gv_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            FilesTopic item = (FilesTopic)gv.SelectedItem;
            string imgUrlStr = "";

            if (App.SelectedDocumentTopic != null)
            {
                oBtnOpenDocInDeepZoom.IsEnabled = true;
                oBtnOpenDocInBrowser.IsEnabled = true;
            }
            else
            {
                oBtnOpenDocInDeepZoom.IsEnabled = false;
                oBtnOpenDocInBrowser.IsEnabled = false;
            }
            
            if (item != null)
            {
                oImage.Source = null;
                imgUrlStr = @"http://sp.korablik.local" + item.ServerRelativeUrl;
                oBtnOpenFileInBrowser.IsEnabled = true;
                oBtnOpenFileInBrowser.NavigateUri = new Uri(imgUrlStr, UriKind.Absolute);
                oBtnOpenDocInDeepZoom.IsEnabled = true;
                App._SelFileName = imgUrlStr;
            }
            else
            {
                imgUrlStr = @"http://sp.korablik.local/images/download.jpg";
                oBtnOpenFileInBrowser.IsEnabled = false;
                oBtnOpenFileInBrowser.NavigateUri = new Uri(imgUrlStr, UriKind.Absolute);
            }
            ImageBrush ib = new ImageBrush();
            BitmapImage bmi;
            ib = new ImageBrush();
            bmi = new BitmapImage(new Uri(imgUrlStr, UriKind.RelativeOrAbsolute));
            ib.ImageSource = bmi;
            ib.Stretch = Stretch.UniformToFill;
            PlaceHolder.Background = ib;
        }
        #endregion

        #region Common methods

        public void FlipFrame(double DirectionalScalarX)
        {
            Storyboard sb = new Storyboard();
            DoubleAnimation da1 = new DoubleAnimation();
            da1.From = -5.0;
            da1.To = -355.0;
            da1.Duration = new Duration(TimeSpan.FromMilliseconds(550.0));
            SineEase se = new SineEase();
            se.EasingMode = EasingMode.EaseInOut;
            da1.EasingFunction = se;

            Storyboard.SetTarget(da1, button1.Projection);
            Storyboard.SetTargetProperty(da1, new PropertyPath("RotationX"));

            DoubleAnimationUsingKeyFrames da2 = BuildKeyFrames(1.0, 80.0, 1.0, 35.0, DirectionalScalarX, 5.0);
            Storyboard.SetTarget(da2, button1.Projection);
            Storyboard.SetTargetProperty(da2, new PropertyPath("RotationY"));

            sb.Children.Add(da1);
            sb.Children.Add(da2);
            sb.Begin();

        }
        DoubleAnimationUsingKeyFrames BuildKeyFrames(double Mass, double SpringConstant, double Dampening, double ForceMultiplier, double DirectionalScalar, double offset)
        {
            int sample = 75; //in ms
            int duration = 10000; //in ms

            //declare physics constants
            double lamda = Dampening / (2 * Math.Sqrt(SpringConstant * Mass));
            double omega_not = Math.Sqrt(SpringConstant / Mass);
            double omega_d = omega_not * Math.Sqrt(1.0 - Math.Pow(lamda, 2.0));
            double amplitude = DirectionalScalar * ForceMultiplier;

            DoubleAnimationUsingKeyFrames double_animation = new DoubleAnimationUsingKeyFrames();
            LinearDoubleKeyFrame frame;

            for (int i = 0; i < (duration / sample); i++)
            {
                frame = new LinearDoubleKeyFrame();
                frame.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromMilliseconds(i * sample));
                frame.Value = offset + amplitude * Math.Exp(-1 * lamda * omega_not * (double)sample * i / 1000) * Math.Sin(omega_d * i * sample / 1000);
                double_animation.KeyFrames.Add(frame);
            }

            return double_animation;
        }

        #endregion

        #region Data

        public static void Invalidate(object sender, DownloadStringCompletedEventArgs e)
        {
            App._SelDoc_data.Clear();
            #region if error
            if (e.Error != null)
            {
                return;
            }
            #endregion
            #region Parse
            XDocument xDoc = XDocument.Parse(e.Result);
            var query = from g in xDoc.Descendants("tbl")
            select new
            {
                AuthorName = (string)g.Element("AuthorName"),
                AuthorID = ((int?)g.Element("AuthorID")) ?? -1,
                AuthorLoginName = (string)g.Element("AuthorLoginName"),
                FileName = (string)g.Element("FileName"),
                url = (string)g.Element("url"),
                ServerRelativeUrl = (string)g.Element("ServerRelativeUrl"),
                FileTimeCreated = (DateTime?)g.Element("FileTimeCreated"),
                FileTimeLastModified = (DateTime?)g.Element("FileTimeLastModified"),
                FileRequiresCheckout = (bool)g.Element("FileRequiresCheckout"),
                FileModifiedByID = ((int?)g.Element("FileModifiedByID")) ?? -1,
                FileModifiedByLoginName = (string)g.Element("FileModifiedByLoginName"),
                FileModifiedByName = (string)g.Element("FileModifiedByName"),
                FileIconUrl = (string)g.Element("FileIconUrl"),
                FileCheckInComment = (string)g.Element("FileCheckInComment"),
                FileLength = ((long?)g.Element("FileLength")) ?? -1
            };
            foreach (var n in query)
            {
                FilesTopic o = new FilesTopic();
                o.AuthorName = n.AuthorName;
                o.AuthorID = n.AuthorID;
                o.AuthorLoginName = n.AuthorLoginName;
                o.FileName = n.FileName;
                o.url = n.url;
                o.ServerRelativeUrl = n.ServerRelativeUrl;
                o.FileTimeCreated = n.FileTimeCreated;
                o.FileTimeLastModified = n.FileTimeLastModified;
                o.FileRequiresCheckout = n.FileRequiresCheckout;
                o.FileModifiedByID = n.FileModifiedByID;
                o.FileModifiedByLoginName = n.FileModifiedByLoginName;
                o.FileModifiedByName = n.FileModifiedByName;
                o.FileIconUrl = n.FileIconUrl;
                o.FileCheckInComment = n.FileCheckInComment;
                o.FileLength = n.FileLength;
                App._SelDoc_data.Add(o);
            }
            #endregion
        }

        #endregion

    }

}
